'use client';

import RtcDebugPanel from '@/components/RtcDebugPanel';
import WebrtcNav from '@/components/WebrtcNav';
import { useIceConnectionMonitor, useRTCDataChannel } from '@/lib/webrtc';
import React, { useEffect, useMemo, useState } from 'react';
import { io, Socket } from 'socket.io-client';
type PeerConnectionInfo = {
	pc: RTCPeerConnection;
	role: 'caller' | 'callee';
};

let socket: Socket;
let roomId = 'room-1';
let selfId = crypto.randomUUID();
let localStream: MediaStream | null = null;
let pcMap = new Map<string, PeerConnectionInfo>();
// const setPcMap = (fn: () => any) =>{

// 	pcMap = fn()

// }
// const [pcMap, setPcMap] = useState<Map<string, PeerConnectionInfo>>(
// 	new Map(),
// );

/**
 * 创建 RTCPeerConnection 实例并处理事件监听
 * @param remoteUserId 远端用户 ID
 * @returns RTCPeerConnection 实例
 */
function createPeerConnection(remoteUserId: string): RTCPeerConnection {
	const pc = new RTCPeerConnection({
		iceServers: [
			{
				urls: 'stun:124.221.59.25:3478',
				username: 'test',
				credential: '123456',
			},
			{
				urls: 'turn:124.221.59.25:3478',
				username: 'test',
				credential: '123456',
			},
		],

		//@ts-ignore
		// continualGatheringPolicy: 'gather_continually',
	});

	// 发送 ICE 候选信息到对方
	pc.onicecandidate = (event) => {
		if (event.candidate) {
			console.log('发送 ICE 候选信息:', event.candidate);
			socket.emit('candidate', {
				roomId,
				from: selfId,
				to: remoteUserId,
				candidate: event.candidate,
			});
		}
		if (event.candidate === null) {
			console.log('✅ 所有 ICE 候选收集完毕');
		}
	};

	// 接收远端媒体流并绑定到 video 元素
	pc.ontrack = (event) => {
		console.log('接收到媒体流:', event.streams);
		const remoteVideo = document.getElementById(
			'remote-video',
		) as HTMLVideoElement;
		const remoteStream = event.streams[0];
		console.log('✅ 接收到远端媒体流:', remoteStream);
		console.log('🎥 视频轨道:', remoteStream.getVideoTracks());
		console.log('🎤 音频轨道:', remoteStream.getAudioTracks());

		remoteVideo.srcObject = remoteStream;
	};

	// 添加本地媒体流轨道
	if (localStream) {
		console.log('创建 RTCPeerConnection 实例:', localStream?.getTracks());
		localStream.getTracks().forEach((track) => {
			pc.addTrack(track, localStream!); // or just `localStream` since we already checked
		});
	} else {
		console.warn('Local stream is not available.');
	}

	return pc;
}

/**
 * 主动发起呼叫
 * @param remoteUserId 被呼叫用户 ID
 * @returns 创建的 RTCPeerConnection 实例
 */
async function makeCall(
	remoteUserId: string,
	role: 'caller' | 'callee',
): Promise<RTCPeerConnection> {
	const pc = createPeerConnection(remoteUserId);
	pcMap.set(remoteUserId, { role: role, pc });

	// 创建并设置本地 Offer
	const offer = await pc.createOffer({ iceRestart: true });
	console.log('Created offer:', offer);

	await pc.setLocalDescription(offer);

	// 向服务器发送 Offer 消息
	socket.emit('offer', {
		roomId,
		from: selfId,
		to: remoteUserId,
		sdp: offer,
	});

	return pc;
}

/**
 * 获取本地摄像头和麦克风权限并播放
 */
async function connectLocalMedia(): Promise<void> {
	if (localStream) return; // 避免重复获取

	try {
		localStream = await navigator.mediaDevices.getUserMedia({
			video: true,
			audio: true,
		});

		const localVideo = document.getElementById(
			'local-video',
		) as HTMLVideoElement;
		if (localVideo) {
			localVideo.srcObject = localStream;
		}
	} catch (err) {
		console.error('获取本地媒体失败:', err);
		alert('无法访问摄像头或麦克风，请检查权限设置。');
	}
}

/**
 * One2One 视频通话页面组件
 */
const One2One = () => {
	const [peers, setPeers] = useState<{ userId: string; role: string }[]>([]);
	const [index, setIndex] = useState(0);
	const [timstamp, setTimestamp] = useState(0);
	const [muted, setMuted] = useState(false);
	const [input, setInput] = useState('');
	// const [pcMap, setPcMap] = useState<Map<string, PeerConnectionInfo>>(
	// 	new Map(),
	// );

	// 获取当前选中用户的 PeerConnection（用于调试面板）
	const curPc = useMemo(() => {
		return peers[index]?.userId ? pcMap.get(peers[index].userId) : undefined;
	}, [peers, index, timstamp]);
	const { iceState } = useIceConnectionMonitor(curPc?.pc || null, {
		onStateChange: (state) => console.log('ICE 状态变化:', state),
		onDisconnected: () => console.log('连接断开，正在尝试重连...'),
		onFailed: () => console.error('连接失败，请检查网络'),
		autoRestart: true,
	});
	const { isOpen, sendMessage } = useRTCDataChannel({
		pc: curPc?.pc || null,
		label: 'chat',
		options: {
			ordered: true,
			maxPacketLifeTime: 3000,
			// protocol: 'json',
		},
		onMessage: (msg) => {
			console.log('收到消息:', msg);
		},
	});

	useEffect(() => {
		// 初始化 Socket 连接
		socket = io('https://lizhan.fun', { path: '/perf/v1/socket.io' });

		socket.on('connect', () => {
			console.log('已连接到信令服务器');
		});

		// 收到房间信息：当前已加入的用户列表
		socket.on('joined', ({ roomId: r, selfId: me, peers: peerList }) => {
			console.log('加入房间:', r, '用户ID:', me, '成员:', peerList);
			setPeers(peerList);
		});

		// 收到对方发来的 Offer 请求
		socket.on('offer', async ({ from, sdp }) => {
			console.log('收到 Offer:', from, sdp);
			const pc = createPeerConnection(from);
			setTimestamp(Date.now());
			pcMap.set(from, { role: 'callee', pc });

			await pc.setRemoteDescription(new RTCSessionDescription(sdp));
			const answer = await pc.createAnswer();
			await pc.setLocalDescription(answer);

			socket.emit('answer', {
				roomId,
				from: selfId,
				to: from,
				sdp: answer,
			});

			// setPcMap((prev) => {
			// 	const map = new Map(prev);
			// 	map.set(from, { pc, role: 'callee' });
			// 	return map;
			// });
		});

		// 收到 Answer 响应
		socket.on('answer', async ({ from, sdp }) => {
			const pcInfo = pcMap.get(from);
			if (pcInfo && !pcInfo.pc.currentRemoteDescription) {
				await pcInfo.pc.setRemoteDescription(new RTCSessionDescription(sdp));
				console.log(`已设置来自 ${from} 的 Answer`);
			}
		});

		// 收到 ICE 候选信息
		socket.on('candidate', async ({ from, candidate }) => {
			const pcInfo = pcMap.get(from);
			if (pcInfo && candidate) {
				try {
					await pcInfo.pc.addIceCandidate(new RTCIceCandidate(candidate));
				} catch (err) {
					console.error(`添加 ICE 候选失败:`, err);
				}
			}
		});
		socket.on('user-left', ({ roomId, userId }) => {
			console.log(`${userId} 离开了房间 ${roomId}`);

			// 更新用户列表：从前端状态中删除该用户
			setPeers((prev) => prev.filter((peer) => peer.userId !== userId));
		});

		// 清理资源
		return () => {
			socket.disconnect();
			pcMap.forEach((pcInfo) => pcInfo.pc.close());
			// setPcMap(new Map());
		};
	}, []);

	/**
	 * 处理呼叫按钮点击
	 */
	const handleCall = async () => {
		console.log('开始呼叫');
		if (peers.length === 0) {
			console.warn('房间内没有其他用户可呼叫');
			alert('当前房间无其他用户');
			return;
		}

		const targetPeer = peers[index];
		if (!targetPeer) return;

		// 避免重复呼叫
		if (pcMap.has(targetPeer.userId)) {
			console.log(`已存在与 ${targetPeer.userId} 的连接`);
			return;
		}

		try {
			const pc = await makeCall(targetPeer.userId, 'caller');
			setTimestamp(Date.now());
			// setPcMap((prev) => {
			// 	const map = new Map(prev);
			// 	map.set(targetPeer.userId, { pc, role: 'caller' });
			// 	return map;
			// });
		} catch (err) {
			console.error('发起呼叫失败:', err);
			alert('呼叫失败，请检查网络或重试');
		}
	};
	/**
	 * 处理离开房间按钮点击
	 */
	const handleLeave = () => {
		socket.emit('leave', { roomId, userId: selfId });
		setPeers([]);
		pcMap.forEach((pcInfo) => pcInfo.pc.close());
	};

	const handleMute = () => {
		setMuted(!muted);
		localStream?.getAudioTracks().forEach((track) => {
			track.enabled = !muted;
		});
	};

	return (
		<div>
			<WebrtcNav text="1对1通话">
				当前连接状态：<strong>{iceState}</strong>
			</WebrtcNav>

			<div className="xs:space-x-4 space-x-2 flex my-4 flex-wrap">
				<button
					className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded"
					onClick={() =>
						socket.emit('join', {
							roomId,
							userId: selfId,
							role: 'audience',
							mode: 'p2p',
						})
					}
				>
					加入房间
				</button>

				<button
					className="bg-red-500 hover:bg-red-700 text-white font-bold py-2 px-4 rounded"
					onClick={handleLeave}
				>
					离开房间
				</button>

				<button
					className="bg-green-500 hover:bg-green-700 text-white font-bold py-2 px-4 rounded"
					onClick={handleCall}
				>
					呼叫 {'用户'}
				</button>

				<button
					className="bg-gray-500 hover:bg-gray-700 text-white font-bold py-2 px-4 rounded"
					onClick={connectLocalMedia}
				>
					开启视频
				</button>
			</div>
			<div className="mt-4 space-x-4 sm:flex justify-center items-start">
				<button
					className="bg-red-500 hover:bg-red-700 text-white font-bold py-2 px-4 rounded"
					onClick={handleMute}
				>
					{muted ? '取消静音' : '静音'}
				</button>
			</div>

			<div className="mt-4 space-x-4 sm:flex justify-center items-start">
				{/* 本地视频 */}
				<div>
					<h1 className="text-xl m-0 text-center">本地视频</h1>
					<video
						id="local-video"
						className="border rounded-md mx-auto"
						autoPlay
						playsInline
						muted
						width={320}
						height={240}
					/>
				</div>

				{/* 远端视频 */}
				<div>
					<h1 className="text-xl m-0 text-center">远端视频</h1>
					<video
						id="remote-video"
						className="border rounded-md mx-auto"
						autoPlay
						playsInline
						width={320}
						height={240}
					/>
				</div>

				{/* 调试面板 */}
			</div>
			<div className="mt-4 flex items-center sm:px-10 px-2">
				<span>{isOpen?'链接成功':'无连接'}</span>
				{/* 状态 */}
				<textarea
					className="flex-1 p-2 border rounded-md"
					rows={2}
					onChange={(e) => setInput(e.target.value)}
				/>
				<button
					className="ml-2 px-4 py-2 bg-blue-500 text-white rounded-md"
					onClick={() => sendMessage(input)}
				>
					发送
				</button>
			</div>
			{/* 用户列表 */}
			<ul className="p-2 text-sm">
				{peers.map((peer, i) => (
					<li
						key={peer.userId}
						className={`cursor-pointer p-2 rounded-sm text-center ${
							i === index ? 'bg-blue-600 text-white' : 'hover:bg-gray-200'
						}`}
						onClick={() => setIndex(i)}
					>
						{peer.userId}
					</li>
				))}
			</ul>
			{curPc && <RtcDebugPanel pc={curPc.pc} role={curPc.role} />}
		</div>
	);
};

export default One2One;
